
package nz.ac.massey.webtech.chat;

import java.util.*;
import java.util.concurrent.*;
import javax.servlet.http.HttpSession;

/**
 * Utility class to manage multiple conversations between clients (sessions).
 * @author jens dietrich
 */
public class ConversationManager {
    // associates sessions with message queues
    static Map<HttpSession,Queue<Message>> messageQueues = new ConcurrentHashMap<HttpSession,Queue<Message>>();

    // associates conversation names with associates sessions 
    static Map<String,Set<HttpSession>> participants = new ConcurrentHashMap<String,Set<HttpSession>>();

    public static void joinConversation(HttpSession session,String conversation,String userName) {
        // TODO user should leave other conversations if there are any
        
        session.getServletContext().log("session for " + userName + " joining or creating conversation " + conversation);
        
        Set<HttpSession> sessions = participants.get(conversation);
        if (sessions==null) {
            sessions = new HashSet<HttpSession>();
            participants.put(conversation, sessions);
        }
        sessions.add(session);
        messageQueues.put(session, new ArrayBlockingQueue<Message>(100));
        session.setAttribute("_conversation", conversation);
        session.setAttribute("_user",userName);
    }
    
    public static void disconnect (HttpSession session) {
        String conversation = (String)session.getAttribute("_conversation");
        String user = (String)session.getAttribute("_user");
        
        Set<HttpSession> sessions = participants.get(conversation);
        if (sessions!=null) {
            sessions.remove(session);
        }
        messageQueues.remove(session);
        session.getServletContext().log("cleaned up session for user " + user + ", conversation " + conversation);
    }
    
    public static Set<String> getConversations () {
        return participants.keySet();
    }
    
    public static void postMessage(HttpSession session,String text) {
        
        
        String conversation = (String)session.getAttribute("_conversation");
        String user = (String)session.getAttribute("_user");
        Message message = new Message(user,text);
        
        session.getServletContext().log("posting message by user " + user + " to conversation " + conversation);
        
        Set<HttpSession> sessions = participants.get(conversation);
        
        // put message in queue of all other participanting sessions
        if (sessions!=null) {
            for (HttpSession s:sessions) {
                if (s!=session) {
                    Queue<Message> queue = messageQueues.get(s);
                    // careful as we use weak maps here ! 
                    if (queue!=null) {
                        queue.add(message);
                    }
                }
            }
        }
    }
    
    public static List<Message> fetchMessages(HttpSession session)  {
        
        // String conversation = (String)session.getAttribute("_conversation");
        // String userName = (String)session.getAttribute("_user");
        // session.getServletContext().log("fetching message for user " + userName + " and conversation " + conversation);
        
        Queue<Message> messageQueue = messageQueues.get(session);
        if (messageQueue!=null) {
            List<Message> messages = new ArrayList<Message>();
            // fetch at most 100 messages
            while (!messageQueue.isEmpty() && messages.size()<100) {
                messages.add(messageQueue.poll());
            }
            return messages;
        }
        else {
            // could use static empty list instance to optimise this
            return new ArrayList<Message>();
        }
    }
    
}
